package org.springblade.tms.module.car.base;

import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.logging.log4j.util.Strings;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.tms.global.entity.TimeInterval;
import org.springblade.tms.global.enums.*;
import org.springblade.tms.global.exception.CommonException;
import org.springblade.tms.module.approval.entity.TMApproval;
import org.springblade.tms.module.approval.service.IApprovalService;
import org.springblade.tms.module.car.dto.CarDto;
import org.springblade.tms.module.car.entity.TMCar;
import org.springblade.tms.module.car.service.ICarService;
import org.springblade.tms.module.car.vo.CarVo;
import org.springblade.tms.module.car.vo.TMCarVO;
import org.springblade.tms.module.carriercarrelation.entity.TMCarrierCarRelation;
import org.springblade.tms.module.carriercarrelation.service.ICarrierCarRelationService;
import org.springblade.tms.module.sap.base.SapRequestService;
import org.springblade.tms.module.userinfo.dto.CarrierAuditReq;
import org.springblade.tms.module.userinfo.entity.TMUserInfo;
import org.springblade.tms.module.userinfo.service.IUserInfoService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @projectName: BladeX
 * @package: org.springblade.tms.module.car.base
 * @className: CarManagementService
 * @author: yr
 * @description: 车辆管理服务
 * @date: 2022/3/9 11:41
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class CarManagementService {
	@Resource
	private ICarService carService;
	@Resource
	private IUserInfoService userInfoService;
	@Resource
	private ICarrierCarRelationService carrierCarRelationService;
	@Resource
	private IApprovalService approvalService;
	@Resource
	private SapRequestService sapRequestService;

	/**
	 * @param car:
	 * @return R
	 * @author yr
	 * @description 查询车辆列表
	 * @date 2022/3/8 13:48
	 */
	public R<IPage> list(TMCarVO car, Query query, TimeInterval timeInterval) {
		//即将到期查询参数
		LocalDateTime expireDate = LocalDateTime.now().plusMonths(1);
		List<Long> driverIds = new ArrayList<>();
		if (Strings.isNotBlank(car.getCarrierId())) {
			List<TMCarrierCarRelation> carrierCarRelations = carrierCarRelationService.lambdaQuery()
				.select(TMCarrierCarRelation::getRelationCarNo)
				.eq(TMCarrierCarRelation::getRelationCarrierNo, car.getCarrierId())
				.list();
			driverIds = carrierCarRelations.stream().map(TMCarrierCarRelation::getRelationCarNo).collect(Collectors.toList());
		}
		Long userId = AuthUtil.getUser().getUserId();
		TMUserInfo tmUserInfo = userInfoService.lambdaQuery().eq(TMUserInfo::getParentId, userId).one();
		IPage<TMCar> page = carService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMCar()).lambda()
			.like(car.getCarNo() != null && !car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo())
			.like(car.getBindCarNo() != null && !car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
			.eq(car.getApprovalStatus() != null && !car.getApprovalStatus().isEmpty(), TMCar::getApprovalStatus, car.getApprovalStatus())
			.eq(car.getCarType() != null && !car.getCarType().isEmpty(), TMCar::getCarType, car.getCarType())
			.eq(car.getTransportGoodsType() != null && !car.getTransportGoodsType().isEmpty(), TMCar::getTransportGoodsType, car.getTransportGoodsType())
			.ge(timeInterval.getStart() != null, TMCar::getCreateTime, timeInterval.getStart())
			.le(timeInterval.getEnd() != null, TMCar::getCreateTime, timeInterval.getEnd())
			.and(car.getExpireDate(), tmUserInfoLambdaQueryWrapper -> tmUserInfoLambdaQueryWrapper
				.le(TMCar::getCertificationBindCarCheckValidEnd, expireDate).or()
				.le(TMCar::getCertificationCarCheckValidEnd, expireDate).or()
				.le(TMCar::getCertificationCarWorkValidEnd, expireDate).or()
				.le(TMCar::getCertificationBindCarWorkValidEnd, expireDate).or()
				.le(TMCar::getContainerReportValidEnd, expireDate).or()
				.le(TMCar::getCertificateTankTruckEnd, expireDate).or()
				.le(TMCar::getVehicleInsuranceValidEnd, expireDate))
			.notIn(!driverIds.isEmpty(), TMCar::getId, driverIds)
			.orderByDesc(TMCar::getUpdateTime,TMCar::getId));
		//判断当前用户是否为承运商
		if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			List<TMCarrierCarRelation> list = carrierCarRelationService.lambdaQuery()
				.select(TMCarrierCarRelation::getRelationCarNo)
				.eq(TMCarrierCarRelation::getRelationCarrierNo, tmUserInfo.getId())
				.list();
			List<Long> driverId = list.stream().map(TMCarrierCarRelation::getRelationCarNo).collect(Collectors.toList());
			page = carService.page(Condition.getPage(query), Condition.getQueryWrapper(new TMCar())
				.lambda().in(!driverId.isEmpty(), TMCar::getId, driverId).apply(driverId.isEmpty(), "1=2")
				.like(car.getCarNo() != null && !car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo())
				.like(car.getBindCarNo() != null && !car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
				.eq(car.getApprovalStatus() != null && !car.getApprovalStatus().isEmpty(), TMCar::getApprovalStatus, car.getApprovalStatus())
				.eq(car.getCarType() != null && !car.getCarType().isEmpty(), TMCar::getCarType, car.getCarType())
				.eq(car.getTransportGoodsType() != null && !car.getTransportGoodsType().isEmpty(), TMCar::getTransportGoodsType, car.getTransportGoodsType())
				.ge(timeInterval.getStart() != null, TMCar::getCreateTime, timeInterval.getStart())
				.le(timeInterval.getEnd() != null, TMCar::getCreateTime, timeInterval.getEnd())
				.notIn(!driverIds.isEmpty(), TMCar::getId, driverIds)
				.orderByDesc(TMCar::getUpdateTime,TMCar::getId));
		}
		page.getRecords().forEach(car1 -> car1.setApprovalStatus(ApprovalStatusEnum.getDescriptionByValue(car1.getApprovalStatus())));
		//把返回值转换为带驳回原因的vo
		List<Long> ids = page.getRecords().stream().map(TMCar::getId).collect(Collectors.toList());
		List<TMApproval> tmApprovalList = approvalService.lambdaQuery().in(!ids.isEmpty(), TMApproval::getRelationId, ids)
			.apply(ids.isEmpty(), "1=2").list();
		Map<Long, String> RemarkMap = tmApprovalList.stream().collect(Collectors.toMap(TMApproval::getRelationId, TMApproval::getRemarkReject));
		LinkedList<CarVo> list = new LinkedList<>();
		for (TMCar record : page.getRecords()) {
			CarVo carVo = BeanUtil.copy(record, CarVo.class);
			carVo.setEnableGps(WhetherEnum.getValueByDescription(record.getEnableGps()));
			carVo.setEsv(WhetherEnum.getValueByDescription(record.getEsv()));
			carVo.setFireOff(WhetherEnum.getValueByDescription(record.getFireOff()));
			carVo.setRemarkReject(RemarkMap.get(record.getId()));
			list.add(carVo);
		}
		IPage pages = page;
		pages.setRecords(list);
		return R.data(pages);
	}

	/**
	 * @param carDto:
	 * @return R
	 * @author yr
	 * @description 新增或修改车辆
	 * @date 2022/3/16 10:24
	 */
	public R saveOrUpdate(CarDto carDto, TMUserInfo tmUserInfo) {
		TMCar car = BeanUtil.copy(carDto, TMCar.class);
		car.setFireOff(WhetherEnum.getDescriptionByValue(carDto.getFireOff()));
		car.setEsv(WhetherEnum.getDescriptionByValue(carDto.getEsv()));
		car.setEnableGps(WhetherEnum.getDescriptionByValue(carDto.getEnableGps()));
		//carId为空时为新增，不为空时为修改
		if (car.getId() == null) {
			TMCar tmCar;
			if (carDto.getCarType().equals(CarType.TRAILER.getValue())) {
				tmCar = carService.lambdaQuery().eq(!car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
					.eq(TMCar::getCarType, CarType.TRAILER.getValue()).one();
			} else {
				tmCar = carService.lambdaQuery().eq(!car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo()).one();
			}
			if (tmCar != null) {
				if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
					if (carService.lambdaQuery()
						.eq(!car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo())
						.ne(TMCar::getCarType, carDto.getCarType())
						.apply(car.getCarNo().isEmpty(),"1=2")
						.one() != null) {
						throw CommonException.throwCommonException("当前车牌号已存在");
					}
					if (carService.lambdaQuery()
						.eq(!car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
						.ne(TMCar::getCarType, carDto.getCarType())
						.apply(car.getBindCarNo().isEmpty(),"1=2")
						.one() != null) {
						throw CommonException.throwCommonException("当前车牌号已存在");
					}
					if (carrierCarRelationService.lambdaQuery().eq(TMCarrierCarRelation::getRelationCarNo, tmCar.getId())
						.eq(TMCarrierCarRelation::getRelationCarrierNo, tmUserInfo.getId()).one() != null) {
						CommonException.throwCommonException("车辆已存在");
					}
					R<Object> r = new R<>();
					r.setCode(206);
					r.setSuccess(true);
					r.setMsg("系统中已存在该车辆，是否进行绑定？");
					return r;
				} else {
					throw CommonException.throwCommonException("当前车牌号已存在");
				}
			}
			car.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			boolean save = carService.save(car);
			//新增审批单
			TMCar one = new TMCar();
			if (carDto.getCarType().equals(CarType.TRAILER.getValue())) {
				one = carService.lambdaQuery().eq(TMCar::getBindCarNo, car.getBindCarNo())
					.eq(TMCar::getCarType, CarType.TRAILER.getValue()).one();
			} else {
				one = carService.lambdaQuery().eq(TMCar::getCarNo, car.getCarNo()).one();
			}
			TMApproval approval = new TMApproval();
			approval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			approval.setRelationId(one.getId());
			approval.setRelationTableName(TableNameEnum.CAR.value());
			approvalService.save(approval);

			if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
				TMCarrierCarRelation tmCarrierCarRelation = new TMCarrierCarRelation();
				tmCarrierCarRelation.setRelationCarrierNo(tmUserInfo.getId());
				tmCarrierCarRelation.setRelationCarNo(one.getId());
				carrierCarRelationService.save(tmCarrierCarRelation);
			}
			return R.status(save);
		} else {
			TMCar one = carService.lambdaQuery().ne(TMCar::getId, car.getId())
				.and(tmCarLambdaQueryWrapper -> tmCarLambdaQueryWrapper.eq(!car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo())
					.or().eq(!car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
					.or().eq(!car.getBindCarNo().isEmpty(), TMCar::getCarNo, car.getBindCarNo())).one();
			if (one != null) {
				throw CommonException.throwCommonException("当前车牌号已存在");
			}
			car.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			boolean update = carService.updateById(car);
			//修改审批单状态为待审核
			TMApproval tmApproval = approvalService.lambdaQuery().eq(TMApproval::getRelationId, car.getId()).one();
			tmApproval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
			tmApproval.setRemarkReject("");
			approvalService.updateById(tmApproval);
			return R.status(update);
		}
	}

	/**
	 * @param carrierAuditReq:
	 * @return R
	 * @author yr
	 * @description 车辆审核
	 * @date 2022/3/16 10:25
	 */
	public R check(List<CarrierAuditReq> carrierAuditReq) {
		if (carrierAuditReq.size() == 1) {
			CarrierAuditReq auditReq = carrierAuditReq.get(0);
			TMCar tmCar = carService.getById(auditReq.getId());
			TMApproval tmApproval = new TMApproval();
			tmApproval.setRelationId(auditReq.getId());
			TMApproval approval = approvalService.getOne(Condition.getQueryWrapper(new TMApproval()).lambda()
				.eq(TMApproval::getRelationId, auditReq.getId()));
			if (auditReq.getPass()) {
				tmCar.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue());
				approval.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue());
			} else {
				tmCar.setApprovalStatus(ApprovalStatusEnum.REJECTED.getValue());
				approval.setApprovalStatus(ApprovalStatusEnum.REJECTED.getValue());
				approval.setRemarkReject(auditReq.getReasonForRejection());
			}
			Boolean update = carService.updateById(tmCar);
			Boolean updateById = approvalService.updateById(approval);
			if (tmCar.getApprovalStatus().equals(ApprovalStatusEnum.PASSED.getValue())) {
				ArrayList<TMCar> carList = new ArrayList<>();
				carList.add(tmCar);
				R driverMasterData = sapRequestService.vehicleMasterData(carList, SapActionEnum.S.getValue());
				if (driverMasterData.getMsg().equals("操作失败")) {
					throw CommonException.throwCommonException("上报TM失败");
				}
			}
			return R.status(update && updateById);
		} else {
			List<Long> ids = carrierAuditReq.stream().map(CarrierAuditReq::getId).collect(Collectors.toList());
			List<TMCar> tmCars = carService.lambdaQuery().in(TMCar::getId, ids).list();
			tmCars.forEach(car -> car.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue()));
			boolean updateBatchById = carService.updateBatchById(tmCars);
			List<TMApproval> tmApprovalList = approvalService.lambdaQuery().in(TMApproval::getRelationId, ids).list();
			tmApprovalList.forEach(approval -> approval.setApprovalStatus(ApprovalStatusEnum.PASSED.getValue()));
			boolean batchById = approvalService.updateBatchById(tmApprovalList);
			R driverMasterData = sapRequestService.vehicleMasterData(tmCars, SapActionEnum.S.getValue());
			if (driverMasterData.getMsg().equals("操作失败")) {
				throw CommonException.throwCommonException("上报TM失败");
			}
			return R.status(batchById && updateBatchById);
		}
	}

	/**
	 * @param ids:
	 * @return R
	 * @author yr
	 * @description 批量删除车辆
	 * @date 2022/3/14 16:42
	 */
	public R delete(List<Long> ids) {
		//判断当前用户是否为承运商
		Long userId = AuthUtil.getUser().getUserId();
		TMUserInfo tmUserInfo = userInfoService.lambdaQuery().eq(TMUserInfo::getParentId, userId).one();
		if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			carrierCarRelationService.remove(Condition.getQueryWrapper(new TMCarrierCarRelation())
				.lambda().eq(TMCarrierCarRelation::getRelationCarrierNo, tmUserInfo.getId())
				.in(TMCarrierCarRelation::getRelationCarNo, ids));
			List<TMCarrierCarRelation> list = carrierCarRelationService.lambdaQuery().in(TMCarrierCarRelation::getRelationCarNo, ids)
				.select(TMCarrierCarRelation::getRelationCarNo).list();
			List<Long> driverIds = list.stream().map(TMCarrierCarRelation::getRelationCarNo).collect(Collectors.toList());
			ids.removeAll(driverIds);
			if (!ids.isEmpty()) {
				List<TMCar> tmCarList = carService.lambdaQuery().in(TMCar::getId, ids).list();
				carService.deleteLogic(ids);
				reportTm(tmCarList);
			}
			return R.status(true);
		} else {
			List<TMCar> tmCarList = carService.lambdaQuery().in(TMCar::getId, ids).list();
			boolean deleteLogic = carService.deleteLogic(ids);
			reportTm(tmCarList);
			return R.status(deleteLogic);
		}
	}

	//将删除状态上报到tm
	private void reportTm(List<TMCar> tmCarList) {
		R driverMasterData = sapRequestService.vehicleMasterData(tmCarList, SapActionEnum.D.getValue());
		if (driverMasterData.getMsg().equals("操作失败")) {
			throw CommonException.throwCommonException("上报TM失败");
		}
	}

	//导入excel新增车辆
	public R save(CarDto carDto, TMUserInfo tmUserInfo, BladeUser user) {
		TMCar car = BeanUtil.copy(carDto, TMCar.class);
		car.setTenantId(user.getTenantId());
		car.setCreateUser(user.getUserId());
		car.setCreateDept(Long.valueOf(user.getDeptId()));
		TMCar tmCar;
		if (carDto.getCarType().equals(CarType.TRAILER.getValue())) {
			tmCar = carService.lambdaQuery().eq(!car.getBindCarNo().isEmpty(), TMCar::getBindCarNo, car.getBindCarNo())
				.eq(TMCar::getCarType, CarType.TRAILER.getValue()).one();
		} else {
			tmCar = carService.lambdaQuery().eq(!car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo()).one();
		}
		if (tmCar != null) {
			if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
				if (carService.lambdaQuery().eq(!car.getCarNo().isEmpty(), TMCar::getCarNo, car.getCarNo())
					.ne(TMCar::getCarType, carDto.getCarType()).one() != null) {
					throw CommonException.throwCommonException("当前车牌号已存在");
				}
				if (carrierCarRelationService.lambdaQuery().eq(TMCarrierCarRelation::getRelationCarNo, tmCar.getId())
					.eq(TMCarrierCarRelation::getRelationCarrierNo, tmUserInfo.getId()).one() != null) {
					CommonException.throwCommonException("车辆已存在");
				}
				R<Object> r = new R<>();
				r.setCode(206);
				r.setSuccess(true);
				r.setMsg("系统中已存在该车辆，是否进行绑定？");
				return r;
			} else {
				throw CommonException.throwCommonException("当前车牌号已存在");
			}
		}
		car.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
		boolean save = carService.save(car);
		//新增审批单
		TMCar one = new TMCar();
		if (carDto.getCarType().equals(CarType.TRAILER.getValue())) {
			one = carService.lambdaQuery().eq(TMCar::getBindCarNo, car.getBindCarNo())
				.eq(TMCar::getCarType, CarType.TRAILER.getValue()).one();
		} else {
			one = carService.lambdaQuery().eq(TMCar::getCarNo, car.getCarNo()).one();
		}
		TMApproval approval = new TMApproval();
		approval.setApprovalStatus(ApprovalStatusEnum.PENDING_REVIEW.getValue());
		approval.setRelationId(one.getId());
		approval.setRelationTableName(TableNameEnum.CAR.value());
		approval.setTenantId(user.getTenantId());
		approvalService.save(approval);

		if (tmUserInfo != null && tmUserInfo.getUserType().equals(UserTypeEnum.CARRIER.getValue())) {
			TMCarrierCarRelation tmCarrierCarRelation = new TMCarrierCarRelation();
			tmCarrierCarRelation.setRelationCarrierNo(tmUserInfo.getId());
			tmCarrierCarRelation.setRelationCarNo(one.getId());
			tmCarrierCarRelation.setTenantId(user.getTenantId());
			carrierCarRelationService.save(tmCarrierCarRelation);
		}
		return R.status(save);
	}
}
